import { EyeOutlined, EyeInvisibleOutlined } from '@ant-design/icons-vue';
import * as storage from '@/util/storage.js';
import { assignStatusOptions } from './const.js';

export const inputValueToInt = R.compose( Number.parseInt, R.path(['target', 'value']) );

export const OptionsFlatted = R.reduce(
  (result, o) => {
    result.push( R.pick(['value', 'label'], o) );
    Reflect.has(o, 'options') && result.concat( OptionsFlatted(o.options) );
    return result;
  },
  []
);

export function addOrDel(v, xSet, force) {
  const action = force || xSet.has(v) ? 'delete' : 'add';
  xSet[action](v);
}

/** 防止字符串为 `null` 或 `''` */
export const strToArr = R.ifElse( R.identity, R.__, R.always([]) );

/**
 * options to dictionary
 *
 * ```javascript
 * toDic(['value', 'label'], [{ value: 1, label: '男' }, { value: 2, label: '女' }]);
 * // => { 1: '男', 2: '女' }
 * ```
 */
export const toDic = R.curry(
  (ps, xs) => R.compose( R.fromPairs, R.map(R.props(ps)) )(xs)
);

export const optsToDic = toDic(['value', 'label']);

export const xsToOpts = R.map(R.compose( R.zipObj(['value', 'label']), R.repeat(R.__, 2) ));

/**
 * 指定旧 key 映射成新的
 *
 * ```javascript
 * rename({ a: 'AAA' }, { a: 1, b: 2 });
 * // => { AAA: 1, b: 2 }
 * ```
 */
export const rename = R.curry((oldToNewDic, o) => {
  const NewToOldDic = R.compose( R.fromPairs, R.map(R.reverse), R.toPairs );
  const omitOldKey = R.omit(R.keys(oldToNewDic));

  return R.mergeRight(
    omitOldKey(o),
    R.compose( R.map(R.prop(R.__, o)), NewToOldDic )(oldToNewDic)
  );
});

export const detectAsgmnt = R.curry(
  (f, v, o) => f(o.assignmentStatus, R.prop( v, toDic(['label', 'value'], assignStatusOptions) ))
);

export const asgmntLt = detectAsgmnt(R.lt);
export const asgmntEq = detectAsgmnt(R.equals);
export const asgmntGte = detectAsgmnt(R.gte);

// --- 数据标注 ---

export const isNewPatternClasses = R.compose( R.equals('['), R.head );

/** prop `'labels'` -> Label[] */
export const toClasses = R.ifElse(
  isNewPatternClasses,
  R.compose( R.pluck('label'), R.curryN(1, JSON.parse) ),
  strToArr(R.split(',')),
);

/**
 * 用户的题包列表
 * @type {function(() => Object[], number): Object[]}
 */
export const filterUserIdEq = R.curry(
  (XS, id) => R.filter(R.propEq(id, 'userId'), XS())
);

export const PkgListReadOf = filterUserIdEq(() => (storage.readAsObj('pkgList') || []));

/**
 * 
 * @param {ObjDetn.PkgInfo} pkgInfo
 * @param {{ id: number; }[]} fileList 
 * @returns {ObjDetn.pkgInfo}
 */
export function makeFileIdValid(pkgInfo, fileList) {
  /** 若 `pkgInfo.ques` 无效则取 `fileList[0].id` */
  const findValidFile = R.either( R.find(R.propEq(pkgInfo.ques, 'id')), R.head );
  return R.compose( R.mergeRight(pkgInfo), R.zipObj(['ques']), Array.of, R.prop('id'), findValidFile )(fileList);
}

const SiblingPkg = f => pkgListOfUser => {
  const findIndex = R.findIndex(R.propEq( storage.readAsObj('pkgInfo').pkg, 'id' ));
  return R.converge(R.prop, [R.compose( f, findIndex ), R.identity])(pkgListOfUser);
};

const PrevPkg = SiblingPkg(R.dec);
const NextPkg = SiblingPkg(R.inc);

export const NextPkgId = R.compose( R.prop('id'), NextPkg );
export const PrevPkgId = R.compose( R.prop('id'), PrevPkg );

export const VisibleIcon = R.ifElse(R.__, EyeOutlined, EyeInvisibleOutlined);

export function TxtToWords(event) {
  const elem = event.currentTarget;

  return new Promise(resolve => {
    const fr = new FileReader();
    fr.readAsText(elem.files[0]);
    fr.addEventListener('load', R.compose(resolve, R.filter(Boolean), R.split(/\s/), R.path(['target', 'result'])));

    event.currentTarget.value = '';
  });
};
